package com.cfs.custom;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

/**
 * Created by Administrator on 2017/9/27/027.
 */
@Component
public class RedisRepo {

    @Autowired
    private RedisTemplate redisTemplate;

    public void set(Serializable key, Object val){
        redisTemplate.opsForValue().set(key, val);
    }

    public void setEx(Serializable key, Object val, Integer time, TimeUnit util){
        redisTemplate.opsForValue().set(key, val,time,util);
    }

    public void setSessionEx(final String key, final Object val, Integer time, TimeUnit util){
        redisTemplate.execute(new RedisCallback() {
            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                connection.setEx(key.getBytes(), 10000, serialize(val));
                return null;
            }
        });
    }


    public Object getSession(final String key){
       return  redisTemplate.execute(new RedisCallback() {
            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                byte[] by = connection.get(key.getBytes());
                if(by != null){
                    return deserialize(by);
                }
                return null;
            }
        });
    }

    public Object getObj(final String key){
        return  redisTemplate.execute(new RedisCallback() {
            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                byte[] by = connection.get(key.getBytes());
                if(by != null){
                    return deserialize(by);
                }
                return null;
            }
        });
    }

    public Object get(Serializable key){
        return redisTemplate.opsForValue().get(key);
    }

    public void delete(Serializable key){
        redisTemplate.delete(key);
    }



    public static byte[] serialize(Object object) {
        if (object == null) {
            return null;
        }
        ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
        try {
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(object);
            oos.flush();
        }
        catch (IOException ex) {
            throw new IllegalArgumentException("Failed to serialize object of type: " + object.getClass(), ex);
        }
        return baos.toByteArray();
    }

    /**
     * Deserialize the byte array into an object.
     * @param bytes a serialized object
     * @return the result of deserializing the bytes
     */
    public static Object deserialize(byte[] bytes) {
        if (bytes == null) {
            return null;
        }
        try {
            ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
            return ois.readObject();
        }
        catch (IOException ex) {
            throw new IllegalArgumentException("Failed to deserialize object", ex);
        }
        catch (ClassNotFoundException ex) {
            throw new IllegalStateException("Failed to deserialize object type", ex);
        }
    }
}
